package com.yunyao.web.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.yunyao.common.dto.excel.ContractMaterialExcelDto;
import com.yunyao.common.dto.supplier.ContractDto;
import com.yunyao.common.web.util.PageResult;
import com.yunyao.common.web.util.StringUtils;
import com.yunyao.common.web.util.YResult;
import com.yunyao.framework.dto.contract.*;
import com.yunyao.framework.dto.file.FileInfoDto;
import com.yunyao.framework.service.SaleContractService;
import com.yunyao.framework.service.systemtwo.ContractService;
import com.yunyao.framework.vo.contract.ContractContacterVO;
import com.yunyao.framework.vo.contract.ContractMaterialCountVO;
import com.yunyao.framework.vo.contract.ContractMaterialVO;
import com.yunyao.framework.vo.contract.ContractNodePayVO;
import com.yunyao.framework.vo.contract.ContractWirePayVO;
import com.yunyao.web.utils.AliOssUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * @author xingjishuai
 * @date 2024-07-15
 */
@RestController
@RequestMapping("/contract")
@Slf4j
public class ContractController {
    @Autowired
    private SaleContractService saleContractService;

    @Autowired
    private ContractService contractService;

    /**
     * 获取合同材料列表
     *
     * @return
     */
    @GetMapping("/material/list")
    public YResult<PageResult<ContractMaterialVO>> getContractMaterialList(ContractDto contractDto) {
        return contractService.getContractMaterialList(contractDto);
    }
    /**
     * 根据合同条件查询物料统计数据
     *
     * 此方法接收一个合同条件对象，通过该条件查询与合同相关的物料统计数据，
     * 并返回统计数据的详细信息封装在YResult对象中
     *
     * @param contractDto 合同条件数据传输对象，用于查询条件
     * @return YResult<ContractMaterialCountVO> 包含物料统计数据的YResult对象，
     *         包括统计数据和可能的错误或状态信息
     */
    @GetMapping("/material/count")
    public YResult<ContractMaterialCountVO> getContractMaterialCount(ContractDto contractDto) {
        return contractService.getContractMaterialCount(contractDto);
    }

    /**
     * 获取合同付款方式信息
     *
     * @return
     */
    @GetMapping("/wire/pay/info")
    public YResult<ContractWirePayVO> getWirePayInfo(ContractDto contractDto) {
        return contractService.getWirePayInfo(contractDto);
    }

    /**
     * 获取合同付款方式节点信息列表
     *
     * @return
     */
    @GetMapping("/node/pay/list")
    public YResult<PageResult<ContractNodePayVO>> getContractNodePayList(ContractDto contractDto) {
        return contractService.getContractNodePayList(contractDto);
    }

    /**
     * 保存合同付款方式信息
     *
     * @param saveDto
     * @return
     */
    @PostMapping("/wire/pay/save")
    public YResult<String> savePayInfo(@RequestBody ContractWirePaySaveDto saveDto) {
        return contractService.savePayInfo(saveDto);
    }

    /**
     * 处理节点支付删除请求
     *
     * @param deletedDto 包含删除操作相关信息的对象
     * @return 操作结果，包含状态码和消息
     */
    @PostMapping("/node/pay/deleted")
    public YResult<String> nodePayDeleted(@RequestBody @Validated ContractNodePayDeletedDto deletedDto) {
        return contractService.nodePayDeleted(deletedDto);
    }

    /**
     * 保存合同材料信息
     *
     * @param saveDto
     * @return
     */
    @PostMapping("/material/save")
    public YResult<String> saveMaterialInfo(@RequestBody ContractMaterialSaveDto saveDto) {
        return contractService.saveMaterialInfo(saveDto);
    }

    /**
     * 删除合同材料信息
     * @param deletedDto
     * @return
     */
    @PostMapping("/material/deleted")
    public YResult<String> deletedMaterialInfo(@RequestBody @Validated ContractMaterialDeletedDto deletedDto) {
        return contractService.deletedMaterialInfo(deletedDto);
    }

    /**
     * 导入材料文件
     *
     * @return
     */
    @PostMapping("/import/material/file")
    public YResult<String> importMaterialFile(@RequestParam("file") MultipartFile file,
                                              @RequestParam("contractId") String contractId) {
        ContractMaterialImportDto importDto = new ContractMaterialImportDto();
        importDto.setFile(file);
        importDto.setContractId(contractId);
        return contractService.importMaterial(importDto);
    }


    /**
     * 保存联系人信息
     *
     * @param saveDto
     * @return
     */
    @PostMapping("/contacter/save")
    public YResult<String> saveContacterInfo(@RequestBody ContractContacterSaveDto saveDto) {
        if (StringUtils.isEmpty(saveDto.getName()) || StringUtils.isEmpty(saveDto.getPhone())) {
            return YResult.error("联系人姓名和联系方式不能为空");
        }
        return contractService.saveContacterInfo(saveDto);
    }

    /**
     * 保存联系人信息列表
     *
     * @param saveDtos
     * @return
     */
    @PostMapping("/contacter/saveBatch")
    public YResult<String> saveContacterInfos(@RequestBody List<ContractContacterSaveDto> saveDtos) {
        if (CollectionUtils.isEmpty(saveDtos)) {
            return YResult.error("联系人信息不能为空");
        }
        for (ContractContacterSaveDto dto : saveDtos) {
            if (StringUtils.isEmpty(dto.getName()) || StringUtils.isEmpty(dto.getPhone()) || StringUtils.isEmpty(dto.getContractId())) {
                return YResult.error("合同id，联系人姓名和联系方式不能为空");
            }
        }
        return contractService.saveContacterInfoBatch(saveDtos);
    }

    /**
     * 获取联系人信息列表
     *
     * @param contractId
     * @return
     */
    @GetMapping("/contacter/list")
    public YResult<List<ContractContacterVO>> getContacterList(String contractId) {
        return contractService.getContacterList(contractId);
    }

    /**
     * 删除联系人信息
     *
     * @param saveDto
     * @return
     */
    @PostMapping("/contacter/deleted")
    public YResult<String> deletedContacterInfo(@RequestBody ContractContacterSaveDto saveDto) {
        return contractService.deletedContacterInfo(saveDto.getId());
    }


    /**
     * 导出材料文件
     *
     * @return
     */

    @GetMapping("/export/material/file")
    public YResult<String> exportMaterialFile(@RequestParam String contractId,@RequestParam String contractNo, HttpServletResponse response) {
        try {
            List<ContractMaterialExcelDto> contractMaterialExportDtoList =  saleContractService.exportMaterial(contractId);
            try {
                // 这里URLEncoder.encode可以防止中文乱码
                String fileName = URLEncoder.encode(contractNo, String.valueOf(StandardCharsets.UTF_8))+".xlsx";
//                response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
                //设置sheet名
                ExportParams params = new ExportParams();
                params.setSheetName("合同材料信息模版");
                //设置标题
//                params.setTitle("商品信息");
                // 这里需要设置不关闭流
                Workbook workbook = ExcelExportUtil.exportExcel(params, ContractMaterialExcelDto.class, contractMaterialExportDtoList);
                //输出流
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                workbook.write(bos);
                byte[] bytes = bos.toByteArray();
                bos.close();
                try {
                    FileInfoDto fileInfoDto = AliOssUtil.upload(bytes,
                            fileName, null);
                    if (null != fileInfoDto) {
                        return YResult.success(fileInfoDto.getLink());
                    } else {
                        return YResult.error("连接文件服务器失败，请重试");
                    }
                } catch (Exception e) {
                    return YResult.error("下载失败，请重试");
                }
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }catch (Exception e) {
            log.error("导出合同材料失败",e);
        }
        return YResult.error("导出合同材料失败");
    }

}
